﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aspose.Words.Reporting;
using System.Collections;
using System.Reflection;
using Stockholm.SOA.Kaskelot.WCF.DataContracts;
using Kaskelot.SP.Services.Client.Mapping;

namespace Kaskelot.SP.Services
{
	public class IEnumerableMailMergeDataSource : IMailMergeDataSource
	{
		private readonly IEnumerator mEnumerator;
		private readonly string mTableName;

		public IEnumerableMailMergeDataSource(IEnumerable data)
		{
			mEnumerator = data.GetEnumerator();
		}

		public IEnumerableMailMergeDataSource(IEnumerable data, string tableName)
		{
			mEnumerator = data.GetEnumerator();
			mTableName = tableName;
		}

		public IMailMergeDataSource GetChildDataSource(string tableName)
		{
			switch (tableName)
			{
				case "Uppdrag":
					return new IEnumerableMailMergeDataSource(((PersonFull)mEnumerator.Current).Uppdrag, "Uppdrag");
				case "UppdragGrupp":
					return new IEnumerableMailMergeDataSource(((PersonFull)mEnumerator.Current).UppdragGrupp, "UppdragGrupp");
				case "KursTillfalle":
					return new IEnumerableMailMergeDataSource(((PersonFull)mEnumerator.Current).KursTillfalle, "KursTillfalle");
				case "BemanningValdistrikt":
					return new IEnumerableMailMergeDataSource(((ValdistriktFull)mEnumerator.Current).BemanningValdistrikt, "BemanningValdistrikt");
				case "Lokaler":
					return new IEnumerableMailMergeDataSource(((ByggnadFull)mEnumerator.Current).Lokaler, "Lokaler");
				case "Materiel":
					return new IEnumerableMailMergeDataSource(((ByggnadFull)mEnumerator.Current).Materiel, "Materiel");
				case "Skyltar":
					return new IEnumerableMailMergeDataSource(((ByggnadFull)mEnumerator.Current).Skyltar.Select(s => s.ToClientContract()), "Skyltar");
				case "Kontaktpersoner":
					return new IEnumerableMailMergeDataSource(((ByggnadFull)mEnumerator.Current).Kontaktpersoner, "Kontaktpersoner");
				default:
					return null;
			}
		}

		public bool GetValue(string fieldName, out object fieldValue)
		{
			// Use reflection to get the property by name from the current object.
			object obj = mEnumerator.Current;
			PropertyInfo property = null;
			Type currentRecordType = obj.GetType();
			if (fieldName.Contains("."))
			{
				string[] propertyParts = fieldName.Split('.');
				PropertyInfo parentProperty = currentRecordType.GetProperty(propertyParts[0]);
				property = parentProperty.PropertyType.GetProperty(propertyParts[1]);
				object parentObj = parentProperty.GetValue(obj, null);
				obj = parentObj;
			}
			else
			{
				property = currentRecordType.GetProperty(fieldName);
			}

			if (property != null)
			{
				fieldValue = property.GetValue(obj, null);
				return true;
			}

			// Return False to the Aspose.Words mail merge engine to indicate the field was not found.
			fieldValue = null;
			return false;
		}

		public bool MoveNext()
		{
			return mEnumerator.MoveNext();
		}

		public string TableName
		{
			get { return mTableName; }
		}
	}
}
